const formatValFnForArr = values => values??[];
const formatValFnForTxt = values => values?.length ? values[0] : '';
const checkedElementsFilterFn = element => element?.checked;

const metas = [
    {
        typeFn: type => type === 'selector',
        renderFn: prop => {
            const optionsContent = ( prop?.options??[] )
                .map(option => option?.trim())
                .filter(option => option?.length)
                .map((option, index) => <option key={index} value={option}>{option}</option>);
            return <select name={prop.name} onChange={e=>handleChange0(e, prop.name, null, formatValFnForTxt, prop.handleChange)}>{optionsContent}</select>;
        },
    },
    {
        typeFn: type => type === 'checkboxes',
        renderFn: prop =>  ( prop?.options??[] )
                .map(option => option?.trim())
                .filter(option => option?.length)
                .map((option, index) => <label key={index}><input type="checkbox" name={prop?.name} value={option} onChange={e=>handleChange0(e, prop.name, checkedElementsFilterFn, formatValFnForArr, prop.handleChange)}/> {option}</label>),
    },
    {
        typeFn: type => type === 'submit',
        renderFn: prop => <button type="submit">Submit</button>,
    },
    {
        typeFn: type => type?.length,
        renderFn: prop => <input type={prop.type} name={prop.name} onChange={e=> handleChange0(e, prop.name, null, formatValFnForTxt, prop.handleChange)}/>,
    }
];

const handleChange0 = (e, name, elementFilterFn, formatValFn, handleChange) => {
    console.trace(`AInput.handleChange0[input.name=${name}].e`, e);
    if (name?.length) {
        const elements = document.querySelectorAll(`input[name='${name}']`);
        console.trace(`AInput.handleChange0[input.name=${name}].elements`, elements)
        const values = [...new Set([...(elements??[])]
                                       .filter(element => !elementFilterFn || elementFilterFn(element))
                                       .map(element => element?.value?.trim())
                                       .filter(value=>value?.length)
        )];
        console.trace(`AInput.handleChange0[input.name=${name}].values`, values);
        const formattedValue = formatValFn ? formatValFn(values) : null;
        console.trace(`AInput.handleChange0[input.name=${name}].formattedValue`, formattedValue);
        if (handleChange) {
            handleChange({ name: name, value: formattedValue });
        }
    }
};

export default function AInput({ name, type = 'text', options = [], handleChange }) {
    const meta = metas.find(meta => meta.typeFn(type));
    console.trace('AInput.meta', meta);
    if (meta) {
        return (<><p>{name?.length ? (name+':') : ''}</p>{meta.renderFn({ name, type, options, handleChange })}</>);
    }
};